package org.lee.app.impl;

import org.lee.app.Collection;
import org.lee.app.Iterator;
import org.lee.app.domain.Employee;
import org.lee.app.domain.Link;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * GroupStructure
 * 组织构架集合
 *
 * @author dralee
 * @date 2021-11-23 13:59:30
 **/
public class GroupStructure implements Collection<Employee, Link> {

    private String groupId;
    private String groupName;
    // 员工列表
    private Map<String, Employee> employeeMap = new ConcurrentHashMap<>();
    // 组织架构关系 id->list
    private Map<String, List<Link>> linkMap = new ConcurrentHashMap<>();
    // 反向关系链
    private Map<String, String> invertedMap = new ConcurrentHashMap<>();

    public GroupStructure(String groupId, String groupName) {
        this.groupId = groupId;
        this.groupName = groupName;
    }

    @Override
    public boolean add(Employee employee) {
        return null != employeeMap.put(employee.getId(), employee);
    }

    @Override
    public boolean remove(Employee employee) {
        return null != employeeMap.remove(employee.getId());
    }

    @Override
    public boolean addLink(String key, Link link) {
        invertedMap.put(link.getToId(), link.getFromId()); // 反向关系
        if (linkMap.containsKey(key)) {
            return linkMap.get(key).add(link);
        }
        List<Link> links = new LinkedList<>();
        links.add(link);
        return null != linkMap.put(key, links);
    }

    @Override
    public boolean removeLink(String key) {
        return null != linkMap.remove(key);
    }

    @Override
    public Iterator<Employee> iterator() {
        return new Iterator<Employee>() {
            Map<String, Integer> keyMap = new HashMap<>();

            private int totalIndex = 0;

            /**
             * 员工id
             */
            private String fromId = groupId;

            /**
             * 关联到员工id
             */
            private String toId = groupId;

            @Override
            public boolean hasNext() {
                return totalIndex < employeeMap.size();
            }

            @Override
            public Employee next() {
                List<Link> links = linkMap.get(toId);
                int curId = getCursorIndex(toId);
                // 同级节点扫描
                if (null == links) {
                    curId = getCursorIndex(fromId);
                    links = linkMap.get(fromId);
                }
                // 上级节点扫描
                while (curId > links.size() - 1) {
                    fromId = invertedMap.get(fromId);
                    curId = getCursorIndex(fromId);
                    links = linkMap.get(fromId);
                }
                // 获取节点
                Link link = links.get(curId);
                toId = link.getToId();
                fromId = link.getFromId();
                totalIndex++;

                return employeeMap.get(link.getToId());
            }

            private int getCursorIndex(String key) {
                int index = 0;
                if (keyMap.containsKey(key)) {
                    index = keyMap.get(key);
                    keyMap.put(key, ++index);
                } else {
                    keyMap.put(key, index);
                }
                return index;
            }
        };
    }
}
